package cn.kgc.spring.day01.factory;

import cn.kgc.spring.day01.annotations.Autowired;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.ResourceBundle;
import java.util.Set;

/**
 * @author 课工场
 * @date 2024/7/11
 * @description  实例工厂类  帮助创建对象
 *
 * 反射
 */
public class BeanFactory {

    private static final HashMap<String,Object> beans = new HashMap<>();

    static {

        //  解析配置文件  创建对象存储在beans容器中
        ResourceBundle resourceBundle = ResourceBundle.getBundle("bean");
        Set<String> keys = resourceBundle.keySet();
        keys.forEach(key->{
            // 获取key对应的value
            String className = resourceBundle.getString(key);
            try {
                // 通过反射创建对象
                Class<?> aClass = Class.forName(className);
                Constructor<?> declaredConstructor = aClass.getDeclaredConstructor();
                Object o = declaredConstructor.newInstance();
                beans.put(key,o);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });

        //通过以上操作 bean中已经有了全部的配置文件中的对象   维护容器中对象的依赖关系
        beans.forEach((k,v)->{
            Class<?> aClass = v.getClass();
            // 获取类中的属性
            Field[] declaredFields = aClass.getDeclaredFields();
            if (declaredFields!=null){
                for (Field declaredField : declaredFields) {
                    Autowired annotation = declaredField.getAnnotation(Autowired.class);
                    if (annotation!=null){
                        // 获取属性名
                        String name = declaredField.getName();
                        Object o = beans.get(name);
                        try {
                            // 给那个对象的属性赋值
                            declaredField.setAccessible(true);
                            declaredField.set(v,o);
                        } catch (IllegalAccessException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }

        });
    }

   public static  <T> T  getBean(Class<T>  clazz){

       try {
           Constructor declaredConstructor = clazz.getDeclaredConstructor();
           Object o = declaredConstructor.newInstance();
           return  clazz.cast(o);
       } catch (Exception e) {
           throw new RuntimeException(e);
       }
   }


   // 从beans容器中获取对象
   public static Object getBean(String beanName){

        return beans.get(beanName);
   }

    public static <T> T  getBean(String beanName,Class<T> clazz){

        return  clazz.cast(beans.get(beanName)) ;
    }
}
